package com.javasm.pk.domain;

import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 级次编码规则实体
 */
public class GradeCodeRule {

    private static final String regex = "([1-9]\\d{0,}\\|{0,1})+";

    /**
     * 编码规则，例：2|2|2
     * 表示：一共有3级，每级的长度为2
     */
    private String rule;
    /**
     * 各级分段长度，例：2|2|2
     * 则：[2,2,2]
     */
    private int[] codeSection = null;
    /**
     * 各级编码长度，例：2|2|2
     * 则：[2,4,6]
     */
    private int[] codeLength = null;
    /**完整编码长度*/
    private int fullGradeLength;

    public GradeCodeRule(String rule){
        checkRule(rule);
        this.rule = rule;
        parseRule(rule);
    }

    private void parseRule(String rule) {
        StringTokenizer st = new StringTokenizer(rule,"|");
        int count = st.countTokens();
        codeSection = new int[count];
        codeLength = new int[count];
        int index = 0;
        fullGradeLength = 0;
        try {
            while (st.hasMoreTokens()) {
                codeSection[index] = Integer.parseInt(st.nextToken());
                fullGradeLength += codeSection[index];
                codeLength[index++] = fullGradeLength;
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("请提供正确的级次编码规则，例如：2|2|2|2，表示：一共有4级，每级的长度为2");
        }
    }

    /**
     * 得到编码第grade级片段的长度。<br/>
     * 如编码规则为"2/3/2/3"，则：<br/>
     * 2级编码片段长度为3，<br/>
     * 3级编码片段长度为2。<br/>
     * @param grade int 1:代表第一级，依次类推
     * @return int
     */
    public int getSectionLength(int grade) {
        if (grade <= 0) {
            return 0;
        } else {
            return codeSection[--grade];
        }
    }

    /**
     * 获取编码级次
     * 如编码规则为"2|2|2"，则：<br>
     * 编码"1010"的级次为2，<br>
     * 编码"10101010"的级次为-1，表示code跟编码规则不匹配，<br>
     * @param code
     * @return 编码级次
     */
    public int getCodeGrade(String code) {
        if(code==null || code.length()==0) return 0;
        int index = Arrays.binarySearch(codeLength, code.length());
        return index >=0 ? index+1 : -1;
    }

    /**
     * 验证编码规则是否符合规范
     * @param rule
     */
    public void checkRule(String rule) {
        if(!rule.matches(regex)){
            throw new IllegalArgumentException(rule+"：不正确，请提供正确的级次编码规则，例如：2|2|2|2，表示：一共有4级，每级的长度为2");
        }
    }

    /**
     * 得到最大编码级次
     * @return 最大编码级次
     */
    public int getMaxGradeCount(){
        return codeSection.length;
    }

    public String getRule() {
        return rule;
    }

    public void setRule(String rule) {
        this.rule = rule;
    }


    public static void main(String[] args) {
        new GradeCodeRule("2,3,4");
    }
}
